#pragma once
# include<Arduino.h>
# include<ArduinoJson.h>
#include "rpc_handler.hpp"
#include "connection_manager.hpp"
#include "node_manager.hpp"
#include "global.hpp"
#include "pin_list.hpp"
#include "../ganix/all.hpp"

void handler_rpc_change_pin(String call_name, JsonArray args, JsonObject kwargs) {
    int pin = args[0];
    bool flag = args[1];
    pinMode(pin, OUTPUT);
    digitalWrite(pin, flag);
}

void call_rpc_change_pin(String target, int pin, bool flag) {
    Message message(target, ACTION_CHANGE_PIN);
    message.add_arg(pin);
    message.add_arg(flag);
    conn_mgr.call_message_rpc(message);
}

void handler_rpc_heartbeat(String call_name, JsonArray args, JsonObject kwargs) {
    String worker = args[0];
    node_mgr.update(worker);
}

void call_pin_function(String target, String function, String args) {
    Message message(target, function);
    for (String arg : string_split(args, ',')) {
        message.add_arg(arg);
    }
    conn_mgr.call_message_rpc(message);
}

void handler_rpc_pin_sw(String call_name, JsonArray args, JsonObject kwargs) {
    String pin_name = args[0];
    int pin_sw = args[1];
    Serial.println("calling:" + call_name + "[" + pin_name + "]" + "(" + pin_sw + ")");
    accept_pin_sw(pin_name, pin_sw);
}

void handler_rpc_pin_pwm(String call_name, JsonArray args, JsonObject kwargs) {
    String pin_name = args[0];
    float rate = args[1];
    Serial.println("calling:" + call_name + "[" + pin_name + "]" + "(" + rate + ")");
    accept_pin_pwm(pin_name, rate);
}

void call_rpc_pin_none(String pin_name, String pin_action) {
    Message message(TARGET_BROCAST, ACTION_PIN_NONE);
    message.add_arg(pin_name);
    message.add_arg(pin_action);
    message.add_arg(WORKER_NAME);
    conn_mgr.call_message_rpc(message);
}

void handler_rpc_pin_none(String call_name, JsonArray args, JsonObject kwargs) {
    String pin_name = args[0];
    String pin_action = args[1];
    String worker = args[2];
    Serial.printf("pin action not found!\n\t name:%s\n\t action:%s\n\t worker:%s\n", pin_name.c_str(), pin_action.c_str(), worker.c_str());
}

void init_rpc_handler() {
    rpc_handler.regist(ACTION_CHANGE_PIN, handler_rpc_change_pin);
    rpc_handler.regist(ACTION_HEARTBEAT, handler_rpc_heartbeat);
    rpc_handler.regist(ACTION_PIN_SW, handler_rpc_pin_sw);
    rpc_handler.regist(ACTION_PIN_PWM, handler_rpc_pin_pwm);
    rpc_handler.regist(ACTION_PIN_NONE, handler_rpc_pin_none);
}